home *** CD-ROM | disk | FTP | other *** search
/ User's Choice Windows CD / User's Choice Windows CD (CMS Software)(1993).iso / misc1 / iv26_w30.zip / SOURCES / MENU.C < prev    next >
C/C++ Source or Header  |  1980-01-03  |  7KB  |  300 lines

  1. /*
  2.  * Copyright (c) 1987, 1988, 1989 Stanford University
  3.  *
  4.  * Permission to use, copy, modify, distribute, and sell this software and its
  5.  * documentation for any purpose is hereby granted without fee, provided
  6.  * that the above copyright notice appear in all copies and that both that
  7.  * copyright notice and this permission notice appear in supporting
  8.  * documentation, and that the name of Stanford not be used in advertising or
  9.  * publicity pertaining to distribution of the software without specific,
  10.  * written prior permission.  Stanford makes no representations about
  11.  * the suitability of this software for any purpose.  It is provided "as is"
  12.  * without express or implied warranty.
  13.  *
  14.  * STANFORD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
  15.  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
  16.  * IN NO EVENT SHALL STANFORD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
  17.  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
  18.  * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
  19.  * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
  20.  * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  21.  */
  22.  
  23. /*
  24.  * Implementation of common menus.
  25.  */
  26.  
  27. #include <InterViews/box.h>
  28. #include <InterViews/event.h>
  29. #include <InterViews/frame.h>
  30. #include <InterViews/glue.h>
  31. #include <InterViews/menu.h>
  32. #include <InterViews/message.h>
  33. #include <InterViews/painter.h>
  34. #include <InterViews/pattern.h>
  35. #include <InterViews/shape.h>
  36. #include <InterViews/world.h>
  37. #include <stdlib.h>
  38.  
  39. /** class MenuItem **/
  40.  
  41. MenuItem::MenuItem(Interactor* i) : (i) { Init(); }
  42. MenuItem::MenuItem(const char* name, Interactor* i) : (name, i) { Init(); }
  43.  
  44. MenuItem::MenuItem(
  45.     const char* str, Alignment al
  46. ) : (str, new Message(str, al, 2, hfil, 0)) {
  47.     Init();
  48. }
  49.  
  50. MenuItem::MenuItem(
  51.     const char* name,
  52.     const char* str, Alignment al
  53. ) : (name, new Message(str, al, 2, hfil, 0)) {
  54.     Init();
  55. }
  56.  
  57. void MenuItem::Init() {
  58.     SetClassName("MenuItem");
  59. }
  60.  
  61. /** class MenuShadow **/
  62.  
  63. class MenuShadow : public MonoScene {
  64. public:
  65.     int depth;
  66.  
  67.     MenuShadow(Interactor*, int depth = 4);
  68.  
  69.     virtual void Reconfig();
  70.     virtual void Resize();
  71.     virtual void Redraw(Coord, Coord, Coord, Coord);
  72. };
  73.  
  74. MenuShadow::MenuShadow(Interactor* i, int d) {
  75.     depth = d;
  76.     if (i != nil) {
  77.     Insert(new Frame(i));
  78.     }
  79. }
  80.  
  81. void MenuShadow::Reconfig() {
  82.     MonoScene::Reconfig();
  83.     const char* d = GetAttribute("depth");
  84.     if (d != nil) {
  85.     depth = atoi(d);
  86.     }
  87.     shape->width += depth;
  88.     shape->height += depth;
  89. }
  90.  
  91. void MenuShadow::Resize() {
  92.     if (component != nil) {
  93.     Place(component, 0, depth, xmax - depth, ymax);
  94.     }
  95. }
  96.  
  97. void MenuShadow::Redraw(Coord x1, Coord y1, Coord x2, Coord y2) {
  98.     if (x2 >= depth && y1 <= ymax - depth) {
  99.     Pattern* p = output->GetPattern();
  100.     boolean b = output->BgFilled();
  101.     output->SetPattern(gray);
  102.     output->FillBg(false);
  103.     Coord left = max(x1, depth);
  104.     Coord top = min(y2, ymax - depth);
  105.     output->FillRect(canvas, left, y1, x2, top);
  106.     output->SetPattern(p);
  107.     output->FillBg(b);
  108.     }
  109. }
  110.  
  111. /** class Menu **/
  112.  
  113. Menu::Menu(Interactor* i) : (i) { Init(); }
  114. Menu::Menu(const char* name, Interactor* i) : (name, i) { Init(); }
  115.  
  116. void Menu::Init() {
  117.     SetClassName("Menu");
  118.     state = new ControlState;
  119.     state->Reference();
  120.     body = nil;
  121.     depth = 3;
  122.     align = BottomLeft;
  123.     scene = nil;
  124.     world = nil;
  125.     rel_x = 0;
  126.     rel_y = 0;
  127.     ins_x = 0;
  128.     ins_y = 0;
  129. }
  130.  
  131. Menu::~Menu() {
  132.     delete body;
  133.     Unref(state);
  134. }
  135.  
  136. void Menu::SetBody(Interactor* i) { body = i; }
  137. void Menu::SetAlign(Alignment a) { align = a; }
  138. void Menu::SetDepth(int d) { depth = d; }
  139.  
  140. void Menu::SetBodyState(ControlState* s) {
  141.     Unref(state);
  142.     state = s;
  143.     s->Reference();
  144. }
  145.  
  146. void Menu::SetScene(Scene* s) {
  147.     if (scene != nil) {
  148.     delete scene;
  149.     }
  150.     scene = s;
  151.     body = scene->Root();
  152. }
  153.  
  154. void Menu::Include(Control* c) {
  155.     if (scene == nil) {
  156.     scene = new VBox;
  157.     body = new MenuShadow(scene);
  158.     }
  159.     scene->Insert(c);
  160.     c->SetState(GetBodyState());
  161. }
  162.  
  163. void Menu::Reconfig() {
  164.     Control::Reconfig();
  165.     world = GetWorld();
  166.     Setup();
  167. }
  168.  
  169. void Menu::Setup() {
  170.     body->Config(world);
  171.     Shape* s = body->GetShape();
  172.     rel_x = s->width / 2;
  173.     rel_y = s->height / 2;
  174. }
  175.  
  176. void Menu::Popup(Event& e) {
  177.     World* w;
  178.     Coord wx, wy;
  179.     e.GetAbsolute(w, wx, wy);
  180.     if (w != world) {
  181.     world = w;
  182.     Setup();
  183.     }
  184.     InsertBody(wx - rel_x, wy - rel_y);
  185.     State()->Selection(this);
  186. }
  187.  
  188. void Menu::Leave() { }
  189.  
  190. void Menu::Open() {
  191.     Coord x, y;
  192.     Align(align, 0, 0, x, y);
  193.     GetRelative(x, y);
  194.     InsertBody(x, y - body->GetShape()->height);
  195. }
  196.  
  197. void Menu::InsertBody(Coord x, Coord y) {
  198.     ins_x = x;
  199.     ins_y = y;
  200.     world->InsertPopup(body, x, y);
  201.     State()->Push(state);
  202.     state->Activate();
  203.     world->Flush();
  204. }
  205.  
  206. void Menu::Close() {
  207.     Control* action = state->Action();
  208.     if (action != nil) {
  209.     Shape* s = action->GetShape();
  210.     rel_x = s->width / 2;
  211.     rel_y = s->height / 2;
  212.     action->GetRelative(rel_x, rel_y, body);
  213.     }
  214.     state->Pop();
  215.     world->Remove(body);
  216.     world->Flush();
  217. }
  218.  
  219. /** class MenuBar **/
  220.  
  221. MenuBar::MenuBar() { Init(); }
  222. MenuBar::MenuBar(const char* name) { SetInstance(name); Init(); }
  223.  
  224. void MenuBar::Init() {
  225.     SetClassName("MenuBar");
  226.     state = new ControlState;
  227.     state->Reference();
  228. }
  229.  
  230. MenuBar::~MenuBar() {
  231.     Unref(state);
  232. }
  233.  
  234. void MenuBar::Include(Control* c) {
  235.     Insert(c);
  236.     c->SetState(state);
  237. }
  238.  
  239. /** class PulldownMenu **/
  240.  
  241. PulldownMenu::PulldownMenu(Interactor* i) : (i) { Init(); }
  242. PulldownMenu::PulldownMenu(
  243.     const char* name, Interactor* i
  244. ) : (name, i) {
  245.     Init();
  246. }
  247.  
  248. PulldownMenu::PulldownMenu(
  249.     const char* str
  250. ) : (str, new Message(str, Center, 2)) {
  251.     Init();
  252. }
  253.  
  254. PulldownMenu::PulldownMenu(
  255.     const char* name, const char* str
  256. ) : (name, new Message(str, Center, 2)) {
  257.     Init();
  258. }
  259.  
  260. void PulldownMenu::Init() {
  261.     SetClassName("PulldownMenu");
  262.     SetAlign(BottomLeft);
  263. }
  264.  
  265. /** class PullrightMenu **/
  266.  
  267. PullrightMenu::PullrightMenu(Interactor* i) : (i) { Init(); }
  268. PullrightMenu::PullrightMenu(
  269.     const char* name, Interactor* i
  270. ) : (name, i) {
  271.     Init();
  272. }
  273.  
  274. PullrightMenu::PullrightMenu(
  275.     const char* str
  276. ) : (str, new Message(str, Left, 2)) {
  277.     Init();
  278. }
  279.  
  280. PullrightMenu::PullrightMenu(
  281.     const char* name, const char* str
  282. ) : (name, new Message(str, Left, 2)) {
  283.     Init();
  284. }
  285.  
  286. void PullrightMenu::Init() {
  287.     SetClassName("PullrightMenu");
  288.     SetAlign(TopRight);
  289. }
  290.  
  291. /** class PopupMenu **/
  292.  
  293. PopupMenu::PopupMenu() : ((Interactor*)nil) { Init(); }
  294.  
  295. void PopupMenu::Init() {
  296.     SetClassName("PopupMenu");
  297.     SetState(new ControlState);
  298.     SetAlign(Center);
  299. }
  300.